Goal: an location based app!
https://github.com/mikelmaron/Cartonama
http://aeneous.coolwrks.com/sajjad/Cartonama-Workshop-Hasgeek.iso
http://workshop.cartonama.org/
http://groups.google.com/group/cartonama-workshop
Came away with a solid base understanding of what OpenStreetMap is all about ... the motivations and the approach.
http://www.youtube.com/watch?v=fpHKb-SZRh8
source http://news.bbc.co.uk/2/hi/uk_news/magazine/8517057.stm
sourc http://gallery.me.com/dbullington#100816&view=null&bgcolor=black&sel=12
http://voiceofkibera.org/
http://blog.foursquare.com/2012/02/29/foursquare-is-joining-the-openstreetmap-movement-say-hi-to-pretty-new-maps/
Understand how to use a GPS and collect data for OSM
Using the GPS
Record Data
Use of GPSBabel to download GPS data
Connect GPS with USB cable
!sh sudo gpsbabel -i Garmin -f usb: -o gpx -F waypoints.gpx
Facility with JOSM and Potlatch editors.
Understand Tagging, Map Features, Editing Presets in JOSM and Potlatch
http://wiki.openstreetmap.org/wiki/Map_Features
highway = bus_stop
name = Domlur
name:en = Domlur
name:kn = ಡೊಮಲೂರು
http://www.openstreetmap.org/browse/changeset/10839653
http://wiki.openstreetmap.org/wiki/APIs
GET http://api.openstreetmap.org/api/0.6/way/35
1 <osm version="0.6" generator="OpenStreetMap server">
2 <way id="35" visible="true" timestamp="2010-12-06T14:41:05Z"
3 version="5" changeset="6564105" user="blackadder" uid="735">
4 <nd ref="200542"/>
5 <nd ref="274057218"/>
6 <nd ref="1024965354"/>
7 <nd ref="200550"/>
8 <nd ref="1024940305"/>
9 <nd ref="1024940306"/>
10 <nd ref="1024940307"/>
11 <nd ref="200551"/>
12 <nd ref="200553"/>
13 <tag k="highway" v="footway"/>
14 <tag k="is_in" v="Sutton Coldfield"/>
15 <tag k="note" v="Fire Access Route"/>
16 <tag k="surface" v="paved"/>
17 </way>
18 </osm>
1 <presets>
2 <group name="Health Service">
3
4 <item name="Basics">
5 <label text="Health Service" />
6
7 <text key="name" text="Service Name" />
8 <combo key="opening_hours" text="Opening Hours" values="24/7,Mo-Fr 08:30-20:00,Tu-Su 08:00-15:00; Sa 08:00-12:00"
9 default="" delete_if_empty="true" link="http://wiki.openstreetmap.org/wiki/Key:opening_hours" />
10
11 <label text=" " />
12 <text key="contact:phone" text="Mobile"
13 link="http://wiki.openstreetmap.org/wiki/Key:contact" />
14 <text key="contact:email" text="Email"
15 link="http:///wiki.openstreetmap.org/wiki/Key:contact" />
16 </group>
17 </presets>
http://josm.openstreetmap.de/wiki/TaggingPresets
http://wiki.openstreetmap.org/wiki/Develop
OSM bus stop data for Bangalore
http://open.mapquestapi.com/xapi/api/0.6/node[highway=bus_stop][bbox=77.4256,12.8254,77.7844,13.1396]
https://github.com/mikelmaron/Cartonama/blob/master/data/busstops-bangalore.xml
"Raster is faster but vector is correcter."
32.0
0.0
0.0
-32.0
691200.0
4576000.0
(example borrowed from Wikipedia)
POINT(77.58 12.96)LINESTRING(77.56 12.95, 77.57 12.95, 77.58 12.96)POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))POLYGON((0 0, 0 4, 4 4, 4 0, 0 0), (3 3, 3 1, 1 1, 1 3, 3 3))http://geojson.org/
{ "type": "Point", "coordinates": [77.58, 12.96] }
{
"type": "LineString",
"coordinates": [ [100.0, 0.0], [101.0, 1.0] ]
}
{
"type": "Polygon",
"coordinates": [
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]
]
}
{
"type": "Polygon",
"coordinates": [
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],
[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]
]
}
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [77.58, 12.96]},
"properties": {"name": "Bangalore"}
}
N.B. Properties can be any legit JSON object!
{
"type": "FeatureCollection",
"features": [ ... ]
}
$ createdb template_gis
$ createlang plpgsql template_gis
$ psql template_gis </usr/share/postgis/postgis.sql
$ psql template_gis </usr/share/postgis/spatial_ref_sys.sql
$ createdb -Ttemplate_gis my_new_postgis_db
Column | Type | Modifiers
-------------------+------------------------+-----------
f_table_catalog | character varying(256) | not null
f_table_schema | character varying(256) | not null
f_table_name | character varying(256) | not null
f_geometry_column | character varying(256) | not null
coord_dimension | integer | not null
srid | integer | not null
type | character varying(30) | not null
Column | Type | Modifiers
-----------+-------------------------+-----------
srid | integer | not null
auth_name | character varying(256) |
auth_srid | integer |
srtext | character varying(2048) |
proj4text | character varying(2048) |
CREATE TABLE poi (id SERIAL, name VARCHAR);
SELECT AddGeometryColumn('poi','location',4326,'POINT',2);
# \d poi
Table "public.poi"
Column | Type | Modifiers
----------+-------------------+--------------------------------------
id | integer | not null default nextval(...)
name | character varying |
location | geometry |
Check constraints:
"enforce_dims_location" CHECK (st_ndims(location) = 2)
"enforce_geotype_location" CHECK
(geometrytype(location) = 'POINT'::text OR location IS NULL)
"enforce_srid_location" CHECK (st_srid(location) = 4326)
# INSERT INTO poi (name, location)
VALUES ('CIS', 'POINT(77.6375384 12.9647134)');
ERROR: new row for relation "poi" violates check constraint
"enforce_srid_location"
# INSERT INTO poi (name, location)
VALUES ('CIS', 'SRID=4326;POINT(77.6375384 12.9647134)');
INSERT 0 1
# SELECT * FROM poi;
id | name | location
----+------+----------------------------------------------------
2 | CIS | 0101000020E61000006D7CDC6DCD685340A4062EEAEEED2940
(1 row)
# SELECT id, name, AsText(location) FROM poi;
id | name | astext
----+------+------------------------------
2 | CIS | POINT(77.6375384 12.9647134)
(1 row)
"Dimensionally Extended 9 Intersection Model" (DE-9IM)
$ shp2pgsql -s4326 -I world_borders.shp admin0 | psql my_db
Table "public.world_borders"
Column | Type | Modifiers
------------+-----------------------+------------------------------
gid | integer | not null default nextval(...)
cat | double precision |
fips_cntry | character varying(80) |
cntry_name | character varying(80) |
area | double precision |
pop_cntry | double precision |
the_geom | geometry |
Indexes:
"world_borders_pkey" PRIMARY KEY, btree (gid)
"world_borders_the_geom_gist" gist (the_geom)
Check constraints:
"enforce_dims_the_geom" CHECK (st_ndims(the_geom) = 2)
"enforce_geotype_the_geom" CHECK
(geometrytype(the_geom) = 'MULTIPOLYGON'::text ...)
"enforce_srid_the_geom" CHECK (st_srid(the_geom) = 4326)
# SELECT name, cntry_name FROM world_borders, poi
WHERE st_contains(world_borders.the_geom, poi.location);
name | cntry_name
------+------------
CIS | India
(1 row)
SELECT SUM(ST_Area(ST_Transform(the_geom, 32643))) / 1000000
FROM world_borders WHERE cntry_name = 'India';
?column?
------------------
3196343.52393187
(1 row)
SELECT ST_Distance_Sphere(
'POINT(77.6375384 12.9647134)', 'POINT(122.7 37.4)') / 1000;
?column?
------------------
5216.69910277434
(1 row)
# EXPLAIN SELECT name, cntry_name FROM world_borders, poi
WHERE st_contains(world_borders.the_geom, poi.location);
QUERY PLAN
----------------------------------------------------------------------
Nested Loop (cost=0.00..1347.15 rows=1 width=14)
Join Filter: ((world_borders.the_geom && poi.location) AND
_st_contains(world_borders.the_geom, poi.location))
-> Seq Scan on poi (cost=0.00..1.01 rows=1 width=104)
-> Seq Scan on world_borders
(cost=0.00..352.84 rows=3784 width=6982)
(4 rows)
# CREATE INDEX world_borders_the_geom_gist
ON world_borders USING GIST (the_geom);
# EXPLAIN SELECT name, cntry_name FROM world_borders, poi
WHERE st_contains(world_borders.the_geom, poi.location);
QUERY PLAN
----------------------------------------------------------------------
Nested Loop (cost=0.00..1815.00 rows=5 width=42)
Join Filter: _st_contains(world_borders.the_geom, poi.location)
-> Seq Scan on poi (cost=0.00..18.30 rows=830 width=64)
-> Index Scan using world_borders_the_geom_gist on world_borders
(cost=0.00..1.90 rows=1 width=6982)
Index Cond: (the_geom && poi.location)
(6 rows)
$ pgsql2shp my_db poi
Initializing... Done (postgis major version: 1).
Output shape: Point
Dumping: XX [1 rows].
A F/OSS library that speaks dozens and dozens of formats
$ gdalinfo SRTM_fB03_n012e077.tif
Driver: GTiff/GeoTIFF
Files: SRTM_fB03_n012e077.tif
Size is 1201, 1201
Coordinate System is:
GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563,
AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich",0],
UNIT["degree",0.0174532925199433],
AUTHORITY["EPSG","4326"]]
Origin = (76.999583333333334,13.000416666666666)
Pixel Size = (0.000833333333333,-0.000833333333333)
Corner Coordinates:
Upper Left ( 76.9995833, 13.0004167) ( 76d59'58.50"E, 13d 0' 1.50"N)
Lower Left ( 76.9995833, 11.9995833) ( 76d59'58.50"E, 11d59'58.50"N)
Upper Right ( 78.0004167, 13.0004167) ( 78d 0' 1.50"E, 13d 0' 1.50"N)
Lower Right ( 78.0004167, 11.9995833) ( 78d 0' 1.50"E, 11d59'58.50"N)
Center ( 77.5000000, 12.5000000) ( 77d30' 0.00"E, 12d30' 0.00"N)
Band 1 Block=1201x1 Type=Float32, ColorInterp=Gray
$ gdal_translate -of GTiff some_other_format.jpg a_better_format.tif
$ gdal_translate --formats
$ gdalwarp -t_srs EPSG:3875 some_file_in_4326.tif web_mercator.tif
$ gdaladdo satellite_image.tif 2 4 8 16 32
$ ogrinfo world_borders.shp
INFO: Open of `world_borders.shp'
using driver `ESRI Shapefile' successful.
1: world_borders (Polygon)
$ ogrinfo world_borders.shp
Layer name: world_borders
Geometry: Polygon
Feature Count: 3784
Extent: (-180.000000, -90.000000) - (180.000000, 83.623596)
Layer SRS WKT:
(unknown)
CAT: Real (16.0)
FIPS_CNTRY: String (80.0)
CNTRY_NAME: String (80.0)
AREA: Real (15.2)
POP_CNTRY: Real (15.2)
OGRFeature(world_borders):0
CAT (Real) = 1
FIPS_CNTRY (String) = AA
CNTRY_NAME (String) = Aruba
AREA (Real) = 193.00
POP_CNTRY (Real) = 71218.00
POLYGON ((-69.882233 12.41111,-69.946945 12.436666, ...))
$ ogr2ogr -a_srs epsg:4326 world_borders_4326.shp world_borders.shp
$ ogr2ogr -a_srs epsg:4326 -t_srs epsg:3875 world_borders_3875.shp world_borders.shp
$ ogr2ogr -f KML world_borders.kml world_borders.shp
$ ogr2ogr -f PostgreSQL PG:dbname=my_db world_borders.kml
API
$ curl http://api.openstreetmap.org/api/0.6/map?bbox=-0.5,51.25,0.5,51.75
(only returns 50,000 objects)
XAPI
Formats
Planet.osm
$ osm2pgsql -l -d my_db -s -G planet.osm.bz2
$ osm2pgsql -m -d my_db -s -G planet.osm.bz2
$ osm2pgsql -l -d my_db -b -0.5,51.25,0.5,51.75 planet.extract.osm.bz2
Default lives in /usr/share/osm2pgsql/default.style or similar
# OsmType Tag DataType Flags
node,way note text delete
node,way source text delete
node,way created_by text delete
node,way access text linear
node,way admin_level text linear
node,way aerialway text linear
node,way aeroway text polygon
...
http://wiki.openstreetmap.org/wiki/Osmosis
osmosis --read-xml file="planet.osm" --write-apidb database="x"
osmosis --read-xml-change file="planetdiff-1-2.osc"
--read-xml file="planet1.osm"
--apply-change --write-xml file="planet2.osm"
osmosis --read-xml city.osm
--way-key-value keyValueList="railway.tram,railway.tram_stop"
--used-node --write-xml city_tram.osm
bzcat downloaded.osm.bz2 | osmosis\
--read-xml enableDateParsing=no file=-\
--bounding-box top=49.5138 left=10.9351 bottom=49.3866 right=11.201
--write-xml file=-\
| bzip2 > extracted.osm.bz2
http://wiki.openstreetmap.org/wiki/Osmium
/*
run with: osmjs -l sparsetable -j extract-nodes.js OSMFILE
*/
wanted_keys = [ ... ];
Osmium.Callbacks.node = function() {
if(!this.tags["name"] && !this.tags["place_name"]) return;
found_wanted_keys = false;
for (var i = 0; i < wanted_keys.length; i++) {
if (this.tags[wanted_keys[i]]) {
found_wanted_keys = true;
break;
}
}
if (!found_wanted_keys) return;
print(JSON.stringify({
"geom": [this.geom.lon, this.geom.lat],
"tags": this.tags,
"type":"node",
"id": this.id
})
)
}
var shp_pois = Osmium.Output.Shapefile.open('./pois', 'point');
shp_pois.add_field('id', 'integer', 10);
shp_pois.add_field('type', 'string', 32);
shp_pois.add_field('name', 'string', 32);
var node_tags = {
amenity: { restaurant: 'restaurant', pub: 'pub' },
shop: { supermarket: 'supermarket' }
}
(continued...)
Osmium.Callbacks.node = function() {
for (var key in this.tags) {
if (node_tags[key]) {
var type = node_tags[key][this.tags[key]];
if (type) {
shp_pois.add(this.geom, {
id: this.id,
type: type,
name: this.tags.name
});
}
}
}
}
Osmium.Callbacks.end = function() {
shp_pois.close();
}
https://github.com/mikelmaron/Cartonama/blob/master/data/bangalore-bus-shp.zip
What are Map Tiles?
Creating Tiles w/ TileMill
@futura_med: "Kedage Normal", "Futura Medium","Function Pro Medium","Ubuntu Regular","Trebuchet MS Regular","DejaVu Sans Book","unifont Medium";
#bus_stops {
marker-width: 2;
marker-line-color: #00f;
text-fill: #b50d38;
text-name: "[name_kn]";
text-face-name: @futura_med;
text-size: 12;
text-dx: 5;
text-allow-overlap: false;
}
https://tiles.mapbox.com/groundtruth/map/map-busd5lm5
Ways to serve tiles ... TileCache (for imagery), TileStash, MapBox, mod_tile, etc
https://tiles.mapbox.com/groundtruth/map/map-busd5lm5
survey Javascript Mapping APIs (OpenLayers, ModestMaps, GMaps API, Leaflet, Mapstraction)
show nominatim, geonames, overpass api
Create an app using, tiles and search, generated from the collected data.
https://github.com/yuvipanda/POSM http://yuvi.in/POSM/
| Table of Contents | t |
|---|---|
| Exposé | ESC |
| Full screen slides | e |
| Presenter View | p |
| Source Files | s |
| Slide Numbers | n |
| Toggle screen blanking | b |
| Show/hide slide context | c |
| Notes | 2 |
| Help | h |